﻿#include "EColorComboBox.h"
#include <QToolTip>
#include <QPainter>
#include <QVector>
#include <QColorDialog>

namespace pst
{
    EColorComboBox::EColorComboBox(QWidget* parent) :EComboBox(parent)
    {
        setEditable(false);
        m_colorDialogEnabled = false;
        connect(this, SIGNAL(activated(int)), SLOT(emitActivatedColor(int)));
        connect(this, SIGNAL(highlighted(int)), SLOT(emitHighlightedColor(int)));
    }

    void EColorComboBox::enableColorDialog(bool enabled)
    {
        if (m_colorDialogEnabled == enabled) return;
        if (enabled) addItem(tr("More ..."));
        else removeItem(count() - 1);
        m_colorDialogEnabled = enabled;
    }

    bool EColorComboBox::hasColor(const QColor& color)
    {
        int num = count();
        if (m_colorDialogEnabled) num--;
        for (int i = 0; i < num; i++) if (getColor(i) == color) return true;
        return false;
    }

    void EColorComboBox::appendColor(const QColor& color, const QString& name)
    {
        if (!color.isValid() || hasColor(color)) return;
        // 准备位图
        QPixmap pix(16, 16);
        pix.fill(Qt::transparent);
        QPainter painter(&pix);
        painter.setPen(Qt::gray);
        painter.setBrush(QBrush(color));
        painter.drawRect(1, 1, 13, 13);
        // 添加到列表末尾
        int i = count();
        QString tn = name.isEmpty() ? color.name().toUpper() : name;
        if (!m_showColorName)
            tn = "";
        if (!m_colorDialogEnabled)
            addItem(tn, QVariant(color.name()));
        else
        {
            if (m_showColorName)
                insertItem(--i, tn, QVariant(color.name()));
            else
                insertItem(--i, "", QVariant(color.name()));

        }
        setItemIcon(i, QIcon(pix));
        setCurrentIndex(i);
    }
    void EColorComboBox::appendOtherColor()
    {
        //QColor color=QColorDialog::getColor(Qt::red,this,tr("other"));
        //QColor color=Qt::red;
        QPixmap pix(16, 16);
        pix.fill(Qt::transparent);
        QPainter painter(&pix);
        painter.setPen(Qt::gray);
        QConicalGradient conicalGradient(6, 6, 0);
        conicalGradient.setColorAt(0, QColor(255, 0, 0));
        conicalGradient.setColorAt(0.166, QColor(255, 255, 0));
        conicalGradient.setColorAt(0.333, QColor(0, 255, 0));
        conicalGradient.setColorAt(0.5, QColor(0, 255, 255));
        conicalGradient.setColorAt(0.666, QColor(0, 0, 255));
        conicalGradient.setColorAt(0.833, QColor(255, 0, 255));
        conicalGradient.setColorAt(1, QColor(255, 0, 0));

        painter.setBrush(QBrush(conicalGradient));

        //绘制正方形
        //painter.drawRect(1, 1, 13, 13);

        //绘制圆
        painter.drawEllipse(1, 1, 13, 13);

        int i = count();
        //addItem(tr("other"),3);
        if (m_showColorName)
            insertItem(i, tr("Custom..."), 3);
        else
            insertItem(i, "", 3);

        setItemIcon(i, QIcon(pix));
        //setCurrentIndex(i);

    }

    void EColorComboBox::setShowColorName(bool isShow)
    {
        m_showColorName = isShow;
    }

    // Added by jingzhe tao. 2013/07/25
    void EColorComboBox::updateOtherColor(const QColor& color)
    {
        int i = count() - 1;
        //addItem(tr("other"),3);
        if (m_showColorName)
        {
            setItemText(i, tr("Custom(%1)...").arg(color.name()));
        }
        setItemData(i, color.name());
        if (true)//m_showColorName)
        {
            QPixmap pix(16, 16);
            pix.fill(Qt::transparent);
            QPainter painter(&pix);
            painter.setPen(Qt::gray);
            painter.setBrush(QBrush(color));

            //绘制正方形
            //painter.drawRect(1, 1, 13, 13);

            //绘制圆
            painter.drawEllipse(1, 1, 13, 13);

            setItemIcon(i, QIcon(pix));
        }
        setCurrentIndex(i);
    }
    void EColorComboBox::insertColor(const QColor& color, const QString& name, int index)
    {
        if (!color.isValid() || hasColor(color)) return;
        int num = count();
        if (m_colorDialogEnabled) num--;
        if (index >= 0 && index < num)
        {
            QPixmap pix(18, 18);
            QPainter painter(&pix);
            painter.setPen(Qt::gray);
            painter.setBrush(QBrush(color));
            painter.drawRect(1, 1, 13, 13);
            QString tn = name.isEmpty() ? color.name().toUpper() : name;
            if (!m_showColorName)
            {
                tn = "";
            }
            insertItem(index, tn, QVariant(color.name()));
            setItemIcon(index, QIcon(pix));
            setCurrentIndex(index);
        }
        else
        {
            appendColor(color, name);
        }
    }

    QColor EColorComboBox::currentColor() const
    {
        int index = currentIndex();
        return getColor(index);
    }

    void EColorComboBox::setCurrentColor(const QColor& color)
    {
        bool existed = false;
        for (int i = 0; i < (int)count(); i++)
        {
            if (getColor(i) == color)
            {
                setCurrentIndex(i);
                m_lastActivated = color;
                existed = true;
                break;
            }
        }
        if (!existed) {
            m_lastActivated = color;
            updateOtherColor(color);
        }
    }

    QColor EColorComboBox::getColor(int index) const
    {
        if (m_colorDialogEnabled && index >= count() - 1) return QColor();
        else if (index < 0) return QColor();
        else return QColor(itemData(index).toString());
    }

    void EColorComboBox::emitActivatedColor(int index)
    {
        /* if(m_colorDialogEnabled&&index==count()-1)
        {
        QColor col=QColorDialog::getColor(QColor(255, 255, 255), this);
        if(col.isValid())
        {
        appendColor(col, col.name());
        setCurrentColor(col);
        emit activated(col);
        }
        else
        {
        setCurrentColor(m_lastActivated);
        col=m_lastActivated;
        }
        m_lastActivated=col;
        }
        else
        {
        m_lastActivated=QColor(itemData(index).toString());
        emit activated(m_lastActivated);
        }*/
        if (index == count() - 1) {
            QColor color = QColorDialog::getColor(m_lastActivated, this, tr("Custom Color"));
            if (color.isValid()) {
                this->updateOtherColor(color);
                m_lastActivated = QColor(itemData(index).toString());
            }
            else {
                setCurrentColor(m_lastActivated);
            }
            /*if (color != m_lastActivated)
                this->updateOtherColor(color);*/
        }
        else m_lastActivated = QColor(itemData(index).toString());
        emit activated(m_lastActivated);
    }

    void EColorComboBox::emitHighlightedColor(int index)
    {
        if (!m_colorDialogEnabled || index != count() - 1) emit highlighted(getColor(index));
    }

    QSize EColorComboBox::sizeHint() const
    {
        QFontMetrics fm(font());
        return QSize(fm.horizontalAdvance(tr("#RRGGBB")) + 16 + 4 + 20, fm.height() + 4);
        //return QSize(fm.width(tr("#RRGGBB")) + 16 + 4 + 20, fm.height() + 4);
    }

    void EColorComboBox::appendPredefinedColors()
    {
        appendColor(Qt::black, tr("Black"));
        appendColor(Qt::darkBlue, tr("Dark blue"));
        appendColor(Qt::darkGreen, tr("Dark green"));
        appendColor(Qt::darkCyan, tr("Dark cyan"));
        appendColor(Qt::darkRed, tr("Dark red"));
        appendColor(Qt::darkMagenta, tr("Dark magenta"));
        appendColor(Qt::darkYellow, tr("Dark yellow"));
        appendColor(Qt::darkGray, tr("Dark gray"));
        appendColor(Qt::gray, tr("Gray"));
        appendColor(Qt::blue, tr("Blue"));
        appendColor(Qt::green, tr("Green"));
        appendColor(Qt::cyan, tr("Cyan"));
        appendColor(Qt::red, tr("Red"));
        appendColor(Qt::magenta, tr("Magenta"));
        appendColor(Qt::yellow, tr("Yellow"));
        appendColor(Qt::white, tr("White"));
        this->appendOtherColor();
    }
    void EColorComboBox::appendBackgroundColors()
    {
        appendColor(Qt::black, tr("Black"));
        appendColor(Qt::gray, tr("Gray"));
        appendColor(Qt::white, tr("White"));
        this->appendOtherColor();
    }
    void EColorComboBox::clearAllColors()
    {
        clear();
        if (m_colorDialogEnabled) addItem(tr("More ..."));
    }

    bool EColorComboBox::colorDialogEnabled() const
    {
        return m_colorDialogEnabled;
    }
}
